import { createReducer } from 'reduxsauce'
import { REHYDRATE } from 'redux-persist/es/constants'
import { generateUUID } from '@pier88health/p8h-common'
import {
  BOT_ANSWER_QUESTION,
  BOT_EDIT_ANSWER_QUESTION,
  BOT_INPUT,
  BOT_START_EVALUATION,
  BOT_START_JOURNEY,
} from '@ACTIONS/smartAssistant'
import { OUT_PUT_ENUM } from '@CONSTANTS/smartAssistant'
import { LANGUAGE } from '@CONSTANTS/app'
import {
  BotInputParamsITF,
  SmartAssistantQuestionActionITF,
  SmartAssistantStateITF,
} from '@REDUXITF/smartAssistant'
import { AssistantMsgITF, EvaluationChoiceITF } from '@INTERFACES/SmartAssistant'
import { EvaluationResultITF, EvaluationStartITF } from '@INTERFACES/Survey'

const INITIAL_STATE: SmartAssistantStateITF = {
  messages: [],
  assistantDetail: null,
  questions: [],
  currentEvaluation: null
}

const rehydrate = (state: SmartAssistantStateITF, { payload }: { payload: { smartAssistant: SmartAssistantStateITF } }) => {
  if (payload && payload.smartAssistant) {
    return { ...INITIAL_STATE, ...payload.smartAssistant }
  }
  return {
    ...state
  }
}

const handleMessage = (messages: AssistantMsgITF[]): AssistantMsgITF[] => {
  if (!Array.isArray(messages)) return []
  return messages.map(item => {
    const { EvaluationChoice, OutputType, EvaluationAnswer } = item
    if (EvaluationChoice && EvaluationChoice.showChoice) {
      return { ...item, EvaluationChoice: { ...EvaluationChoice, showChoice: false } }
    }
    if (OutputType === OUT_PUT_ENUM.EvaluationAnswer && EvaluationAnswer && EvaluationAnswer.isEdit) {
      return { ...item, EvaluationAnswer: { ...EvaluationAnswer, isEdit: false } }
    }
    return item
  })
}
export default createReducer(INITIAL_STATE, {
  [REHYDRATE]: rehydrate,
  [BOT_START_JOURNEY.FAILURE]: (state, { error }: { error: string }) => ({
    ...state,
    error
  }),
  [BOT_START_JOURNEY.REQUEST]: state => ({
    ...state,
    assistantDetail: null,
    currentEvaluation: null,
    questions: [],
    messages: []
  }),
  [BOT_START_JOURNEY.SUCCESS]: (state, { data }: { data: AssistantMsgITF }) => ({
    ...state,
    assistantDetail: data,
    messages: [{ ...data, isSelf: false, id: generateUUID() }]
  }),
  [BOT_INPUT.REQUEST]: (state, { data }: { data: BotInputParamsITF }) => {
    const { addSendMsg, Text, addReturnMsg } = data
    const messagesNew = handleMessage(state.messages)
    if (!addSendMsg && !addReturnMsg) {
      return state
    }
    if (!addSendMsg) {
      return {
        ...state,
        currentEvaluation: null,
        questions: [],
        messages: [...messagesNew]
      }
    }
    const msg = {
      isSelf: true, id: generateUUID(), Text, OutputType: OUT_PUT_ENUM.Text
    } as AssistantMsgITF
    return {
      ...state,
      currentEvaluation: null,
      questions: [],
      messages: [...messagesNew, msg]
    }
  },
  [BOT_INPUT.SUCCESS]: (state, { data }: { data: AssistantMsgITF }) => ({
    ...state,
    messages: [...state.messages, { ...data, isSelf: false, id: generateUUID() }]
  }),
  [BOT_START_EVALUATION.REQUEST]: (state, { data, isTestBtn }) => {
    const messagesNew = handleMessage(state.messages)
    const msg = {
      isSelf: true,
      id: generateUUID(),
      Text: isTestBtn ? '立即开始' : data?.Title?.[LANGUAGE.ZH],
      OutputType: OUT_PUT_ENUM.Text
    } as AssistantMsgITF
    return {
      ...state,
      messages: [...messagesNew, msg],
      currentEvaluation: null,
      questions: []
    }
  },
  [BOT_START_EVALUATION.SUCCESS]: (state, { result }: { result: EvaluationStartITF }) => {
    const questions = result?.Template?.Questions
    const question = questions?.[0]
    if (!question) return state
    const uuId = generateUUID()
    const msg = {
      EvaluationChoice: { ...question, showChoice: true, uuId },
      id: generateUUID(),
      uuId,
      isSelf: false,
      OutputType: OUT_PUT_ENUM.EvaluationChoice
    } as AssistantMsgITF
    return {
      ...state,
      currentEvaluation: { ...result, uuId, id: generateUUID() },
      questions,
      messages: [...state.messages, msg]
    }
  },
  [BOT_ANSWER_QUESTION.REQUEST]: (state, { message, choice }: SmartAssistantQuestionActionITF) => {
    const { questions, messages: preMessages } = state
    const messageIndex = preMessages.findIndex(item => item.id === message.id)
    if (messageIndex < 0) return state
    const preMessage = preMessages[messageIndex]
    const { uuId } = preMessage

    const { EvaluationChoice } = message
    const newMessage = {
      ...preMessage,
      EvaluationChoice: { ...preMessage.EvaluationChoice, showChoice: false, AnswerChoice: choice, isEdit: false },
      showChoice: false
    } as AssistantMsgITF
    preMessages.splice(messageIndex, 1, newMessage)
    const isEdit = EvaluationChoice?.AnswerChoice || EvaluationChoice?.isEdit
    if (isEdit && EvaluationChoice?.AnswerChoice?.Label === choice?.Label) return { ...state, messages: preMessages }
    const questionIndex = questions.findIndex(item => item.Code === preMessage.EvaluationChoice?.Code)
    let newMessages = [...preMessages]
    if (isEdit) {
      newMessages = newMessages.slice(0, messageIndex + 1)
    }
    newMessages.push({
      uuId,
      EvaluationAnswer: { ...(newMessage.EvaluationChoice || {}), isEdit: true } as EvaluationChoiceITF,
      id: generateUUID(),
      isSelf: true,
      OutputType: OUT_PUT_ENUM.EvaluationAnswer
    } as AssistantMsgITF)

    if (questionIndex + 1 < questions.length) {
      const question = questions[questionIndex + 1]
      newMessages.push({
        EvaluationChoice: { ...question, showChoice: true, uuId: uuId || '' } as EvaluationChoiceITF,
        id: generateUUID(),
        uuId,
        isSelf: false,
        OutputType: OUT_PUT_ENUM.EvaluationChoice
      } as AssistantMsgITF)
    }
    return {
      ...state,
      messages: newMessages
    }
  },
  [BOT_ANSWER_QUESTION.SUCCESS]: (state, { result }: { result: EvaluationResultITF }) => {
    const { messages: preMessages } = state
    const newMessages = handleMessage(preMessages)
    return {
      ...state,
      currentEvaluation: null,
      questions: [],
      messages: [...newMessages, {
        EvaluationResult: result,
        isSelf: false,
        id: generateUUID(),
        OutputType: OUT_PUT_ENUM.EvaluationResult
      } as AssistantMsgITF]
    }
  },
  [BOT_EDIT_ANSWER_QUESTION.REQUEST]: (state, { message }: SmartAssistantQuestionActionITF) => {
    const { messages: preMessages } = state
    const index = preMessages.findIndex(item => message.id === item.id)
    const isChoiceMsg = preMessages[index - 1]?.OutputType === OUT_PUT_ENUM.EvaluationChoice
    // eslint-disable-next-line max-len
    const choiceMsgIndex = isChoiceMsg ? index - 1 : preMessages.findIndex(item => item.uuId === message.uuId && item.EvaluationChoice && item.EvaluationChoice.Code === message.EvaluationAnswer.Code)
    const newMessages = [...preMessages]
    const choiceMsg = { ...preMessages[choiceMsgIndex] }
    newMessages.splice(choiceMsgIndex, 1, {
      ...choiceMsg,
      EvaluationChoice: { ...choiceMsg.EvaluationChoice, showChoice: true, isEdit: true } as EvaluationChoiceITF
    })
    return {
      ...state,
      messages: newMessages
    }
  }
})
